package modele;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Observable;
import java.io.Serializable;
/**
 * Modele du patron MVC.  Classe responsable de gerer les perspectives ainsi que l'image.
 * @author yohan
 *
 */
public class Modele extends Observable implements Snapshotable, Serializable{
	
	//Noms des elements a envoyer au snapshot
	private static final String X_KEY = "x";
	private static final String Y_KEY = "y";
	private static final String ZOOM_KEY = "zoom";
	
	//Multiplicateur de la taille de l'image lorsque le pourcentage
	//de zoom est de 100 pourcent
	private static final float MAX_SIZE_MULTIPLIER = 4;
		
	//Perspective et image a gerer
	private Perspective perspective = new Perspective();
	private MonImage currentImage = MonImage.getInstance();
	
	@Override
	public Snapshot createSnapshot(){
		Snapshot snap = new Snapshot();
		
		//Mise en memoire de tous les parametres necessaires de la perspective
		snap.addValue(X_KEY, perspective.getX());
		snap.addValue(Y_KEY, perspective.getY());
		snap.addValue(ZOOM_KEY, perspective.getZoom());
		
//		System.out.println("Snapshot created");
		
		return snap;
	}
	
	@Override
	public void setSnapshot(Snapshot snap){
		
		//Remise en place des parametres mis en memoire
		perspective = new Perspective();
		perspective.setX((Integer) snap.getValue(X_KEY));
		perspective.setY((Integer) snap.getValue(Y_KEY));
		perspective.setZoom((Integer) snap.getValue(ZOOM_KEY));
		
//		System.out.println("Snapshot loaded");
		aviserAmis(false);
		
	}
	
	/**
	 * Avise les observers
	 */
	private void aviserAmis(boolean affecterVignette){
		setChanged();
		notifyObservers(affecterVignette);
	}
	
	/*
	 * 
	 * MUTATEURS
	 * 
	 */
	
	/**
	 * Set la position de l'image en X
	 */
	public void setImageX(int x){
		perspective.setX(x);
//		System.out.println("Modele: setting image X to " + x);
		aviserAmis(false);
	}
	
	/**
	 * Set la position de l'image en Y
	 */
	public void setImageY(int y){
		perspective.setY(y);
		aviserAmis(false);
	}
	
	/**
	 * Set le zoom de l'image
	 * @param zoomLevel Le zoom desire (entre 1 et 100)
	 */
	public void setImageZoom(int zoomLevel){
		perspective.setZoom(zoomLevel);
		aviserAmis(false);
	}
	
	/**
	 * Set tous les parametres du meme coup
	 * @param x Position en X
	 * @param y Position en Y
	 * @param zoom Le niveau de zoom
	 */
	public void setImageParameters(int x, int y, int zoom){
		setImageX(x);
		setImageY(y);
		setImageZoom(zoom);
		aviserAmis(false);
	}
	
	/*
	 * 
	 * ACCESSEURS
	 * 
	 */
	
	/**
	 * @return la position en X 
	 */
	public int getImageX(){
		return perspective.getX();
	}
	
	/**
	 * @return la position en Y 
	 */
	public int getImageY(){
		return perspective.getY();
	}
	
	public int getImageZoom(){
		return perspective.getZoom();
	}
	
	/**
	 * Charger une image
	 * @param path Le chemin de l'image
	 * @throws IOException Si le path n'existe pas
	 */
	public void loadImage(String path) throws IOException{
		MonImage.getInstance().loadImage(path);
		aviserAmis(true);
	}
	
	/**
	 * Sert a venir chercher l'image en memoire, mais sous sa forme modifiee par le zoom
	 * @return L'image modifiee par le zoom
	 */
	public Image getZoomedImage(){
		BufferedImage scaledImage = (BufferedImage) currentImage.getImage();
		double zoom = perspective.getZoom() / 100f * MAX_SIZE_MULTIPLIER;
		
		int width = (int) (scaledImage.getWidth() * zoom);
		int height = (int) (scaledImage.getHeight() * zoom);
		return scaledImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
		
	}
}
